<script setup>
import { useAppStore, useWMSStore } from '@/stores'
import ExceptionLogger from '@/utils/errorHandler'
import { useBoolean } from '@/hooks/useBoolean'
import proj4 from 'proj4'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import TileWMS from 'ol/source/TileWMS'
import Projection from 'ol/proj/Projection'

const appStore = useAppStore()
const wmsStore = useWMSStore()
const selectedValue = ref('选择要加载的WMS图层')
const wmsURL = ref('')
const layerOptions = ref([])
const loading = ref(false)
const windowWidth = ref(window.innerWidth)
const windowHeight = ref(window.innerHeight)
const adaptHeight = appStore.showTabs ? (appStore.showFooter ? ref(387) : ref(427)) : appStore.showFooter ? ref(427) : ref(472)
const { bool: addLoading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const computedHeight = computed(() => windowHeight.value - adaptHeight.value)

const handleResize = () => {
  windowWidth.value = window.innerWidth
  windowHeight.value = window.innerHeight
}

const handleUpdateValue = async (_, option) => {
  startLoading()
  try {
    wmsStore.setCurrentLayer(option.label)
    await wmsStore.setOpenlayersAddCode()
    if (window.olMap_wms) {
      window.olMap_wms.setTarget(null)
      window.olMap_wms = null
    }
    eval(wmsStore.openlayersAddCode)
  } catch (error) {
    ExceptionLogger.wmsHandleException(error)
  } finally {
    endLoading()
  }
}

const load = async () => {
  if (!ExceptionLogger.isValidURL(wmsURL.value)) return ExceptionLogger.logException('请输入正确的 URL 地址')
  loading.value = true
  startLoading()
  try {
    await wmsStore.initWMSInfo(wmsURL.value)
    await wmsStore.setOpenlayersAddCode()
    if (window.olMap_wms) {
      window.olMap_wms.setTarget(null)
      window.olMap_wms = null
    }
    eval(wmsStore.openlayersAddCode)
  } catch (error) {
    ExceptionLogger.wmsHandleException(error)
  } finally {
    loading.value = false
    endLoading()
  }
}

function initMap() {
  proj4.defs('EPSG:3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs')
  window.olMap_wms = new Map({
    target: document.getElementById('olMap_wms'),
    view: new View({
      projection: new Projection({
        code: 'EPSG:3857',
        extent: [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244],
        units: 'm',
        global: true
      }),
      multiWorld: true
    })
  })
  const tileLayer = new TileLayer({
    source: new TileWMS({
      url: 'https://iserver.supermap.io/iserver/services/map-china400/wms111/China',
      params: {
        LAYERS: 'China',
        FORMAT: 'image/png',
        VERSION: '1.1.1'
      }
    })
  })
  olMap_wms.addLayer(tileLayer)
  olMap_wms.getView().fit([-2.0037508342789248e7, -2.003750834278914e7, 2.0037508342789244e7, 2.0037508342789087e7])
}

watch(
  () => wmsStore.wmsInfo.layer,
  () => {
    selectedValue.value = wmsStore.wmsInfo.layer[0].title
    layerOptions.value = Array.from(wmsStore.wmsInfo.layer).map((item) => ({
      label: item.title,
      value: item.name
    }))
  }
)
watch(
  () => appStore.showTabs,
  () => {
    appStore.showTabs ? (adaptHeight.value += 45) : (adaptHeight.value -= 45)
  },
  { immediate: true }
)
watch(
  () => appStore.showFooter,
  () => {
    appStore.showFooter ? (adaptHeight.value += 40) : (adaptHeight.value -= 40)
  },
  { immediate: true }
)

onMounted(() => {
  window.addEventListener('resize', handleResize)
  initMap()
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

<template>
  <n-card>
    <n-grid :x-gap="0" :y-gap="8" :cols="2">
      <n-gi>
        <n-flex>
          <n-input-group>
            <n-input v-model:value="wmsURL" placeholder="请输入WMS能力文档地址" />
            <n-button type="primary" :loading="loading" @click="load">
              <template #icon>
                <icon-park-outline-loading />
              </template>
              加载
            </n-button>
          </n-input-group>
        </n-flex>
      </n-gi>
      <n-gi>
        <n-flex class="w-50 ml-auto">
          <n-select v-model:value="selectedValue" @update:value="handleUpdateValue" filterable :options="layerOptions" />
        </n-flex>
      </n-gi>
    </n-grid>
  </n-card>
  <n-card :style="{ height: `${computedHeight}px` }" class="flex-1 mt-2">
    <div id="olMap_wms" class="absolute-full"></div>
    <Loading v-if="addLoading" />
  </n-card>
</template>
